K.provides("K.logging.Logger").
run(function(I) {
	var 
	
        loggers = {},
        
        appenders = {},
        
        emit = function(name, tags, message) {
            K.forEach(appenders, function(appender) {
                if (appender.listens(name, tags)) {
                    appender.append(name, tags, message);
                }
            });
        },
        
        /**
         * Logger class
         */
        Logger = K.kin(function(obj, name) {
            var log = function(level) {
                return function(message) {
                    obj.log(level, message);
                };
            };
        
            K.merge(obj, {
                log : function() {
                    var args = K.array(arguments),
                        msg = args.pop();
                        
                    emit(name, args, msg);
                },
                
                fatal : log("FATAL"),
                error : log("ERROR"),
                warn : log("WARN"),
                info : log("INFO"),
                debug : log("DEBUG"),
                trace : log("TRACE")
            });
        });
        
    K.merge(Logger, {
        getLogger : function(name) {
            if (!loggers.hasOwnProperty(name)) {
                loggers[name] = K.logging.Logger(name);
            }
            
            return loggers[name];
        },
        
        addAppender : function(appender) {
        	var id = appender.getId();
        	if (!appenders.hasOwnProperty(id)) {
        		appenders[id] = appender;
        	}
        },
        
        removeAppender : function(appender) {
        	delete appenders[appender.getId()];
        }
    });
    
    return Logger;
});